home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 December / CHIPNET Aralık 1997.iso / linux / redhat / misc / src / install / lateme~1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-11  |  28.6 KB  |  1,112 lines

  1. #include <alloca.h>
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <newt.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/mount.h>
  9. #include <sys/mtio.h>
  10. #include <unistd.h>
  11.  
  12. #include "hd.h"
  13. #include "fs.h"
  14. #include "ftp.h"
  15. #include "install.h"
  16. #include "log.h"
  17. #include "methods.h"
  18. #include "net.h"
  19. #include "scsi.h"
  20. #include "windows.h"
  21.  
  22. struct ftpinfo {
  23.     char * address;
  24.     char * login;
  25.     char * password;
  26.     char * prefix;
  27.     char * proxy;
  28.     int sock;
  29.     struct pkgSet ps;
  30. };
  31.  
  32. struct hdinfo {
  33.     char * device;
  34.     char * type;
  35.     char * dir;
  36. };
  37.  
  38. struct tapeCatalogEntry {
  39.     char * filename;
  40.     int size;
  41. };
  42.  
  43. struct tapeinfo {
  44.     int fd;
  45.     int offset;
  46.     int curr;
  47.     int catalogEntries;
  48.     struct tapeCatalogEntry * catalog;
  49. };
  50.  
  51. /* This was split into two pieces to keep the initial install program small */
  52.  
  53. static int ftpinstStartTransfer(struct ftpinfo * fi, char * filename);
  54. static int ftpinstFinishTransfer(struct ftpinfo * fi);
  55. static int ftpinstGetMappedFile(struct installMethod * method, char * name, 
  56.                         char ** realName, int isPreskel);
  57. static int imageGetFile(struct installMethod * method, char * name, 
  58.             char ** realName, int isPreskel);
  59. static int singleimageSetSymlinks(struct installMethod * method, 
  60.                             struct partitionTable table,
  61.                             struct netConfig * netc, 
  62.                   struct netInterface * intf,
  63.                   struct driversLoaded ** dl);
  64. static int smbSetup(struct installMethod * method, struct partitionTable table,
  65.                struct netConfig * netc, struct netInterface * intf,
  66.                struct driversLoaded ** dl);
  67. static int hdSetup(struct installMethod * method, struct partitionTable table,
  68.                struct netConfig * netc, struct netInterface * intf,
  69.                struct driversLoaded ** dl);
  70. static int hdPrepareMedia(struct installMethod * method,
  71.                 struct fstab * fstab);
  72. static int hdGetPackageSet(struct installMethod * method,
  73.                  struct pkgSet * ps);
  74. static int hdGetComponentSet(struct installMethod * method,
  75.                    struct pkgSet * ps,
  76.                    struct componentSet * cs);
  77. static int ftpSetup(struct installMethod * method, struct partitionTable table,
  78.                 struct netConfig * netc, struct netInterface * intf,
  79.                 struct driversLoaded ** dl);
  80. static int ftpGetPackageSet(struct installMethod * method,
  81.                  struct pkgSet * ps);
  82. static int ftpGetComponentSet(struct installMethod * method,
  83.                    struct pkgSet * ps,
  84.                    struct componentSet * cs);
  85. static int imageGetPackageSet(struct installMethod * method,
  86.                   struct pkgSet * ps);
  87. static int imageGetComponentSet(struct installMethod * method,
  88.                  struct pkgSet * ps,
  89.                  struct componentSet * cs);
  90. static int tapeSetup(struct installMethod * method, struct partitionTable table,
  91.                  struct netConfig * netc, struct netInterface * intf,
  92.                  struct driversLoaded ** dl);
  93. static int tapeGetPackageSet(struct installMethod * method,
  94.                  struct pkgSet * ps);
  95. static int tapeGetComponentSet(struct installMethod * method,
  96.                  struct pkgSet * ps,
  97.                  struct componentSet * cs);
  98. static int tapeGetMappedFile(struct installMethod * method, char * name, 
  99.                         char ** realName, int isPreskel);
  100. static int smbGetSetup(char ** hostptr, char ** dirptr, char ** acctptr,
  101.             char ** pwptr);
  102. static int smbGetPackageSet(struct installMethod * method,
  103.                  struct pkgSet * ps);
  104. static int smbGetComponentSet(struct installMethod * method,
  105.                    struct pkgSet * ps,
  106.                    struct componentSet * cs);
  107.  
  108. static struct installMethod methods[] = {
  109.     { "Local CDROM",         "cdrom", 0, NULL, singleimageSetSymlinks, 
  110.         imageGetFile, 
  111.         imageGetPackageSet, imageGetComponentSet, NULL, NULL },
  112.     { "NFS image",         "nfs", 0, NULL, singleimageSetSymlinks, 
  113.         imageGetFile, 
  114.         imageGetPackageSet, imageGetComponentSet, NULL, NULL },
  115.     { "hard drive",        "hd",  0, NULL, hdSetup, imageGetFile,
  116.         hdGetPackageSet, hdGetComponentSet, hdPrepareMedia, NULL },
  117.     { "FTP",            "ftp", 1, NULL, ftpSetup, ftpinstGetMappedFile,
  118.         ftpGetPackageSet, ftpGetComponentSet, NULL, NULL },
  119. #ifdef __i386__
  120.     { "SMB image",         "smb", 0, NULL, smbSetup, 
  121.         imageGetFile, 
  122.         smbGetPackageSet, smbGetComponentSet, NULL, NULL },
  123. #endif
  124.     { "SCSI Tape",         "tape", 1, NULL, tapeSetup, tapeGetMappedFile,
  125.         tapeGetPackageSet, tapeGetComponentSet, NULL },
  126. } ;
  127. static int numMethods = sizeof(methods) / sizeof(struct installMethod);
  128.  
  129. struct installMethod * findInstallMethod(char * argptr) {
  130.     int i;
  131.  
  132.     for (i = 0; i < numMethods; i++) 
  133.     if (!strcmp(argptr, methods[i].abbrev)) return (methods + i);
  134.  
  135.     return NULL;
  136. }
  137.  
  138. static int imageGetFile(struct installMethod * method, char * name, 
  139.             char ** realName, int isPreskel) {
  140.     static char buf[300];
  141.  
  142.     if (!strcmp(name, "skeleton.cgz") || !strcmp(name, "uglist") ||
  143.     !strcmp(name, "rpmconvert"))
  144.     strcpy(buf, "/tmp/rhimage/RedHat/base/");
  145.     else
  146.     strcpy(buf, "/tmp/rhimage/RedHat/RPMS/");
  147.  
  148.     strcat(buf, name);
  149.     *realName = buf;
  150.  
  151.     return 0;
  152. }
  153.  
  154. static int hdSetup(struct installMethod * method, struct partitionTable table,
  155.                struct netConfig * netc, struct netInterface * intf,
  156.                struct driversLoaded ** dl) {
  157.     newtComponent okay, cancel, form, text, listbox, label, answer, dirEntry;
  158.     int i, j;
  159.     char buf[80];
  160.     struct partition * part = NULL;
  161.     char * type;
  162.     char * dir;
  163.     char * dest;
  164.     char * defaultDevice;
  165.     char * defaultDir;
  166.     int done = 0;
  167.     struct hdinfo * hdi;
  168.  
  169.     if (method->data) {
  170.     hdi = method->data;
  171.     defaultDir = strdup(hdi->dir);
  172.     defaultDevice = hdi->device;
  173.     } else {
  174.     defaultDir = strdup("/");
  175.     defaultDevice = "";
  176.     }
  177.  
  178.     while (!done) {
  179.     newtOpenWindow(10, 4, 64, 17, "Select Partition");
  180.     text = newtTextbox(1, 1, 62, 4, NEWT_TEXTBOX_WRAP);
  181.     newtTextboxSetText(text, "What partition and directory on that "
  182.                 "partition hold the RedHat/RPMS and "
  183.                 "RedHat/base directories?");
  184.     okay = newtButton(15, 13, "Ok");
  185.     cancel = newtButton(38, 13, "Cancel");
  186.  
  187.     form = newtForm(NULL, NULL, 0);
  188.  
  189.     listbox = newtListbox(7, 5, 5, NEWT_LISTBOX_RETURNEXIT);
  190.  
  191.     label = 
  192.         newtLabel(5, 4, "  Device          Begin        End   Size (k)");
  193.  
  194.     for (i = 0, j = 0; i < table.count; i++) {
  195.         if (table.parts[i].type == PART_EXT2 ||
  196.         table.parts[i].type == PART_DOS) {
  197.         sprintf(buf, "/dev/%-5s  %9d  %9d  %9d", table.parts[i].device, 
  198.             table.parts[i].begin, table.parts[i].end, 
  199.             table.parts[i].size);
  200.         newtListboxAddEntry(listbox, buf, &table.parts[i]);
  201.     
  202.         if (!strcmp(table.parts[i].device, defaultDevice)) {
  203.             newtListboxSetCurrent(listbox, j);
  204.         }
  205.  
  206.         j++;
  207.         }
  208.     }
  209.  
  210.     newtFormAddComponent(form, 
  211.                 newtLabel(1, 11, "Directory holding Red Hat:"));
  212.     dirEntry = newtEntry(28, 11, defaultDir, 28, &dir, NEWT_ENTRY_SCROLL);
  213.  
  214.     newtFormAddComponents(form, text, label, listbox, dirEntry,
  215.                 okay, cancel, NULL);
  216.     answer = newtRunForm(form);
  217.                 
  218.     if (answer != cancel) {
  219.         part = newtListboxGetCurrent(listbox);
  220.     }
  221.  
  222.     dir = strdup(dir);
  223.     free(defaultDir);
  224.     defaultDir = dir;
  225.     defaultDevice = part->device;
  226.  
  227.     newtFormDestroy(form);
  228.     newtPopWindow();
  229.  
  230.     if (answer == cancel) return INST_CANCEL;
  231.  
  232.     switch (part->type) {
  233.       case PART_EXT2:    type = "ext2";         break;
  234.       case PART_DOS:    type = "msdos";     break;
  235.       default:    continue;
  236.     }
  237.  
  238.     if (doMount(part->device, "/tmp/hdimage", type, 1, 0))
  239.         continue;
  240.  
  241.     unlink("/tmp/rhimage");
  242.     
  243.     /* the physical device is mounted on /tmp/hdimage, but all
  244.        access are through /tmp/rhimage which points to the RedHat
  245.        directory in /tmp/hdimage */
  246.  
  247.     dest = alloca(strlen(dir) + 20);
  248.     sprintf(dest, "/tmp/hdimage/%s", dir);
  249.  
  250.     if (symlink(dest, "/tmp/rhimage")) {
  251.         messageWindow("Error", "Failed to create /tmp/rhimage "
  252.                 "symlink: %s", strerror(errno));
  253.         umount("/tmp/hdimage");
  254.         continue;
  255.     } 
  256.  
  257.     if (access("/tmp/rhimage/RedHat/base/hdlist", R_OK)) {
  258.         messageWindow("Error", "Device %s does not appear to contain "
  259.             "a Red Hat insallation tree.", part->device);
  260.         umount("/tmp/hdimage");
  261.         continue;
  262.     } 
  263.  
  264.     if (method->data) {
  265.         hdi = method->data;
  266.         free(hdi->dir);
  267.     }
  268.     
  269.     hdi = malloc(sizeof(*hdi));
  270.     hdi->device = part->device;
  271.     hdi->type = type;
  272.     hdi->dir = strdup(dir);
  273.     method->data = hdi;
  274.  
  275.     done = 1; 
  276.  
  277.     umount("/tmp/hdimage");
  278.     }
  279.  
  280.     return 0;
  281. }
  282.  
  283. static int hdGetPackageSet(struct installMethod * method,
  284.                  struct pkgSet * ps) {
  285.     struct hdinfo * hdi = method->data;
  286.     int rc;
  287.  
  288.     if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
  289.     return INST_ERROR;
  290.  
  291.     rc = psUsingDirectory("/tmp/rhimage/RedHat/RPMS", ps);
  292.     
  293.     umount("/tmp/hdimage");
  294.  
  295.     return rc;
  296. }
  297.  
  298. static int hdGetComponentSet(struct installMethod * method,
  299.                    struct pkgSet * ps,
  300.                    struct componentSet * cs) {
  301.     struct hdinfo * hdi = method->data;
  302.     int rc;
  303.  
  304.     if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
  305.     return INST_ERROR;
  306.  
  307.     rc = psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs);
  308.     
  309.     umount("/tmp/hdimage");
  310.  
  311.     return rc;
  312. }
  313.  
  314. static int hdPrepareMedia(struct installMethod * method,
  315.                 struct fstab * fstab) {
  316.     struct hdinfo * hdi = method->data;
  317.     int i;
  318.     char * buf;
  319.  
  320.     for (i = 0; i < fstab->numEntries; i++) {
  321.     if (fstab->entries[i].isMounted &&
  322.         !strcmp(fstab->entries[i].device, hdi->device)) break;
  323.     }
  324.  
  325.     if (i < fstab->numEntries) {
  326.     logMessage("device %s is already mounted -- using symlink",
  327.             fstab->entries[i].device);
  328.     buf = alloca(strlen(fstab->entries[i].mntpoint) + 10);
  329.  
  330.     sprintf(buf, "/mnt/%s", fstab->entries[i].mntpoint);
  331.     
  332.     rmdir("/tmp/hdimage");
  333.     if (symlink(buf, "/tmp/hdimage")) {
  334.         logMessage("failed to create symlink %s: %s\n", 
  335.             buf, strerror(errno));
  336.         messageWindow("Error", "Failed to create symlink for package "
  337.             "source.");
  338.         return INST_ERROR;
  339.     }
  340.     } else {
  341.     logMessage("mounting device which contains packages");
  342.     if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
  343.         return INST_ERROR;
  344.     }
  345.  
  346.     return 0;
  347. }
  348.  
  349. static int imageGetPackageSet(struct installMethod * method,
  350.                   struct pkgSet * ps) {
  351.     return psFromHeaderListFile("/tmp/rhimage/RedHat/base/hdlist", ps);
  352. }
  353.  
  354. static int imageGetComponentSet(struct installMethod * method,
  355.                     struct pkgSet * ps,
  356.                     struct componentSet * cs) {
  357.     return psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs);
  358. }
  359.  
  360. static int singleimageSetSymlinks(struct installMethod * method, 
  361.                             struct partitionTable table,
  362.                             struct netConfig * netc, 
  363.                   struct netInterface * intf,
  364.                   struct driversLoaded ** dl) {
  365.     logMessage("making symlink from /tmp/rhimage to image");
  366.     symlink("rhimage", "/tmp/image");
  367.     return 0;
  368. }
  369.  
  370. /* returns a socket file descriptor, a ftpFinishTransfer() must occur after 
  371.    this call */
  372. static int ftpinstStartTransfer(struct ftpinfo * fi, char * filename) {
  373.     char * buf;
  374.     newtComponent form;
  375.     int fd;
  376.  
  377.     logMessage("ftping %s to a fd", filename);
  378.  
  379.     newtOpenWindow(10, 10, 60, 3, "Retrieving");
  380.  
  381.     buf = alloca(strlen(fi->prefix) + strlen(filename) + 30);
  382.     sprintf(buf, "Retrieving %s...", filename);
  383.     form = newtForm(NULL, NULL, 0);
  384.     newtFormAddComponent(form, newtLabel(1, 1, buf));
  385.  
  386.     newtDrawForm(form);
  387.     newtRefresh();
  388.  
  389.     strcpy(buf, fi->prefix);
  390.     strcat(buf, "/RedHat/");
  391.     strcat(buf, filename);
  392.     fd = ftpGetFileDesc(fi->sock, buf);
  393.  
  394.     return fd;
  395. }
  396.  
  397. static int ftpinstFinishTransfer(struct ftpinfo * fi) {
  398.     newtPopWindow();
  399.  
  400.     return ftpGetFileDone(fi->sock);
  401. }
  402.  
  403. static int ftpinstGetFile(struct ftpinfo * fi, char * filename, char * dest) {
  404.     char * buf;
  405.     newtComponent form;
  406.     int fd, rc;
  407.  
  408.     logMessage("ftping %s as %s", filename, dest);
  409.  
  410.     newtOpenWindow(10, 10, 60, 3, "Retrieving");
  411.  
  412.     buf = alloca(strlen(fi->prefix) + strlen(filename) + 30);
  413.     sprintf(buf, "Retrieving %s...", filename);
  414.     form = newtForm(NULL, NULL, 0);
  415.     newtFormAddComponent(form, newtLabel(1, 1, buf));
  416.  
  417.     newtDrawForm(form);
  418.     newtRefresh();
  419.  
  420.     fd = open(dest, O_WRONLY | O_CREAT, 0644);
  421.     if (fd < 0) {
  422.     messageWindow("Error", "open of %s failed: %s\n", dest, 
  423.             strerror(errno));
  424.     return INST_ERROR;
  425.     }
  426.  
  427.     strcpy(buf, fi->prefix);
  428.     strcat(buf, "/RedHat/");
  429.     strcat(buf, filename);
  430.     rc = ftpGetFile(fi->sock, buf, fd);
  431.  
  432.     close(fd);
  433.  
  434.     newtFormDestroy(form);
  435.     newtPopWindow();
  436.  
  437.     if (rc) {
  438.     messageWindow("ftp", "I cannot get file %s: %s\n", buf,
  439.             ftpStrerror(rc));
  440.     return INST_ERROR;
  441.     }
  442.  
  443.     return 0;
  444. }
  445.  
  446. static int ftpMainSetupPanel(struct ftpinfo * fi, char * doSecondarySetup) {
  447.     newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text, cb;
  448.     char * site, * dir;
  449.  
  450.     if (fi->address) {
  451.     site = fi->address;
  452.     dir = fi->prefix;
  453.     } else {
  454.     site = "";
  455.     dir = "";
  456.     }
  457.  
  458.     if (fi->login || fi->password || fi->login)
  459.     *doSecondarySetup = 'X';
  460.     else
  461.     *doSecondarySetup = ' ';
  462.  
  463.     newtOpenWindow(17, 3, 50, 17, "FTP Setup");
  464.  
  465.     form = newtForm(NULL, NULL, 0);
  466.     okay = newtButton(10, 13, "Ok");
  467.     cancel = newtButton(30, 13, "Cancel");
  468.  
  469.     text = newtTextbox(1, 1, 47, 8, NEWT_TEXTBOX_WRAP);
  470.     newtTextboxSetText(text,
  471.     "Please enter the following information:\n"
  472.     "\n"
  473.     "    o the name or IP number of your FTP server\n"
  474.     "    o the directory on that server containing\n"
  475.     "      Red Hat Linux for your architecure\n");
  476.  
  477.     newtFormAddComponent(form, newtLabel(3, 8, "FTP site name    :"));
  478.     newtFormAddComponent(form, newtLabel(3, 9, "Red Hat directory:"));
  479.  
  480.     siteEntry = newtEntry(22, 8, site, 24, &site, NEWT_ENTRY_SCROLL);
  481.     dirEntry = newtEntry(22, 9, dir, 24, &dir, NEWT_ENTRY_SCROLL);
  482.  
  483.     cb = newtCheckbox(3, 11, "Use non-anonymous ftp or a proxy server",
  484.             *doSecondarySetup, NULL, doSecondarySetup);
  485.  
  486.     newtFormAddComponents(form, text, siteEntry, dirEntry, cb, okay, cancel, 
  487.               NULL);
  488.  
  489.     answer = newtRunForm(form);
  490.     if (answer == cancel) {
  491.     newtFormDestroy(form);
  492.     newtPopWindow();
  493.     
  494.     return INST_CANCEL;
  495.     }
  496.  
  497.     if (fi->address) free(fi->address);
  498.     fi->address = strdup(site);
  499.  
  500.     if (fi->prefix) free(fi->prefix);
  501.     fi->prefix = strdup(dir);
  502.  
  503.     newtFormDestroy(form);
  504.     newtPopWindow();
  505.  
  506.     return 0;
  507. }
  508.  
  509. static int ftpSecondarySetupPanel(struct ftpinfo * fi) {
  510.     newtComponent form, okay, cancel, answer, text, accountEntry;
  511.     newtComponent passwordEntry, proxyEntry;
  512.     char * account, * password, * proxy;
  513.  
  514.     newtOpenWindow(17, 4, 50, 15, "Further FTP Setup");
  515.  
  516.     form = newtForm(NULL, NULL, 0);
  517.     okay = newtButton(10, 11, "Ok");
  518.     cancel = newtButton(30, 11, "Cancel");
  519.  
  520.     text = newtTextbox(1, 1, 47, 8, NEWT_TEXTBOX_WRAP);
  521.     newtTextboxSetText(text,
  522.     "If you are using non anonymous ftp, enter the account "
  523.     "name and password you wish to use below. If you are "
  524.     "using an FTP proxy enter the name of the FTP proxy server "
  525.     "to use.");
  526.  
  527.     newtFormAddComponent(form, newtLabel(3, 6, "Account name :"));
  528.     newtFormAddComponent(form, newtLabel(3, 7, "Password     :"));
  529.  
  530.     newtFormAddComponent(form, newtLabel(3, 9, "FTP Proxy    :"));
  531.  
  532.     accountEntry = newtEntry(18, 6, fi->login, 24, &account, NEWT_ENTRY_SCROLL);
  533.     passwordEntry = newtEntry(18, 7, NULL, 24, &password, 
  534.                 NEWT_ENTRY_SCROLL | NEWT_ENTRY_HIDDEN);
  535.     proxyEntry = newtEntry(18, 9, fi->proxy, 24, &proxy, NEWT_ENTRY_SCROLL);
  536.  
  537.     newtFormAddComponents(form, text, accountEntry, passwordEntry, proxyEntry, 
  538.               okay, cancel, NULL);
  539.  
  540.     answer = newtRunForm(form);
  541.     if (answer == cancel) {
  542.     newtFormDestroy(form);
  543.     newtPopWindow();
  544.     
  545.     return INST_CANCEL;
  546.     }
  547.  
  548.     if (fi->login) free(fi->login);
  549.     if (strlen(account))
  550.     fi->login = strdup(account);
  551.     else
  552.     fi->login = NULL;
  553.  
  554.     if (fi->password) free(fi->password);
  555.     if (strlen(password))
  556.     fi->password = strdup(password);
  557.     else
  558.     fi->password = NULL;
  559.  
  560.     if (fi->proxy) free(fi->proxy);
  561.     if (strlen(proxy))
  562.     fi->proxy = strdup(proxy);
  563.     else
  564.     fi->proxy = NULL;
  565.  
  566.     newtFormDestroy(form);
  567.     newtPopWindow();
  568.  
  569.     return 0;
  570. }
  571.  
  572. static int ftpSetup(struct installMethod * method, struct partitionTable table,
  573.                 struct netConfig * netc, struct netInterface * intf,
  574.                 struct driversLoaded ** dl) {
  575.     struct ftpinfo fi;
  576.     enum { FTP_SETUP_NET, FTP_SETUP_FTP1, FTP_SETUP_FTP2, FTP_SETUP_CHECK, 
  577.         FTP_SETUP_DONE } step = FTP_SETUP_NET;
  578.     int rc, fd;
  579.     char doMore;
  580.  
  581.     memset(&fi, 0, sizeof(fi));
  582.  
  583.     if (method->data)
  584.     memcpy(&fi, method->data, sizeof(fi));
  585.     else
  586.     memset(&fi, 0, sizeof(fi));
  587.  
  588.     while (step != FTP_SETUP_DONE) {
  589.     switch (step) {
  590.  
  591.       case FTP_SETUP_NET:
  592.         rc = bringUpNetworking(intf, netc, dl);
  593.         if (rc) return rc;
  594.         step = FTP_SETUP_FTP1;
  595.         break;
  596.  
  597.       case FTP_SETUP_FTP1:
  598.         rc = ftpMainSetupPanel(&fi, &doMore);
  599.         if (rc == INST_ERROR) 
  600.         return rc;
  601.         else if (rc)
  602.         step = FTP_SETUP_NET;
  603.         else if (doMore == ' ')
  604.         step = FTP_SETUP_CHECK;
  605.         else 
  606.         step = FTP_SETUP_FTP2;
  607.         break;
  608.  
  609.       case FTP_SETUP_FTP2:
  610.         rc = ftpSecondarySetupPanel(&fi);
  611.         if (rc == INST_ERROR) 
  612.         return rc;
  613.         else if (rc)
  614.         step = FTP_SETUP_FTP1;
  615.         else
  616.         step = FTP_SETUP_CHECK;
  617.         break;
  618.  
  619.       case FTP_SETUP_CHECK:
  620.         if ((fi.sock = ftpOpen(fi.address, fi.login, 
  621.                    fi.password ? fi.password : "rhinstall@", 
  622.                    fi.proxy, -1)) < 0) {
  623.         messageWindow("ftp", "I cannot log into machine: %s\n",
  624.                 ftpStrerror(fi.sock));
  625.         step = FTP_SETUP_FTP1;
  626.         break;
  627.         }
  628.  
  629.         
  630.         fd = ftpinstStartTransfer(&fi, "base/hdlist");
  631.         if (fd < 0) {
  632.         newtPopWindow();
  633.         ftpClose(fi.sock);
  634.         step = FTP_SETUP_FTP1;
  635.         break;
  636.         }
  637.  
  638.         if (psFromHeaderListDesc(fd, &fi.ps, 1)) {
  639.         ftpClose(fi.sock);
  640.         step = FTP_SETUP_FTP1;
  641.         break;
  642.         }
  643.  
  644.         ftpinstFinishTransfer(&fi);
  645.  
  646.         if (ftpinstGetFile(&fi, "base/comps", "/tmp/comps")) {
  647.         ftpClose(fi.sock);
  648.         step = FTP_SETUP_FTP1;
  649.         break;
  650.         }
  651.         
  652.         step = FTP_SETUP_DONE;
  653.         break;
  654.  
  655.       case FTP_SETUP_DONE:
  656.         break;
  657.     }
  658.     }
  659.  
  660.     if (method->data) free(method->data);
  661.     method->data = malloc(sizeof(fi));
  662.     memcpy(method->data, &fi, sizeof(fi));
  663.  
  664.     return 0;
  665. }
  666.  
  667. static int ftpGetPackageSet(struct installMethod * method,
  668.                  struct pkgSet * ps) {
  669.     struct ftpinfo * fi = method->data;
  670.  
  671.     *ps = fi->ps;
  672.     return 0;
  673. }
  674.  
  675. static int ftpGetComponentSet(struct installMethod * method,
  676.                    struct pkgSet * ps,
  677.                    struct componentSet * cs) {
  678.     return psReadComponentsFile("/tmp/comps", ps, cs);
  679. }
  680.  
  681. static int ftpinstGetMappedFile(struct installMethod * method, char * name, 
  682.                         char ** realName, int isPreskel) {
  683.     static char sbuf[300];
  684.     char * buf;
  685.     int rc;
  686.     struct ftpinfo * fi = method->data;
  687.  
  688.     if (isPreskel)
  689.     strcpy(sbuf, "/mnt/");
  690.     else
  691.     strcpy(sbuf, "/mnt/var/tmp/");
  692.  
  693.     strcat(sbuf, name);
  694.     *realName = sbuf;
  695.  
  696.     buf = alloca(strlen(name) + 30);
  697.     if (!strcmp(name, "skeleton.cgz") || !strcmp(name, "uglist") ||
  698.     !strcmp(name, "rpmconvert"))
  699.     strcpy(buf, "base/");
  700.     else
  701.     strcpy(buf, "RPMS/");
  702.     strcat(buf, name);
  703.  
  704.     rc = ftpinstGetFile(fi, buf, *realName);
  705.     if (!rc) return 0;
  706.  
  707.     /* Try again, and relogin */
  708.     ftpClose(fi->sock);
  709.  
  710.     if ((fi->sock = ftpOpen(fi->address, fi->login, 
  711.                 fi->password ? fi->password : "rhinstall@", 
  712.                 fi->proxy, -1)) 
  713.         < 0) {
  714.     messageWindow("ftp", "I cannot log into machine: %s\n",
  715.             ftpStrerror(fi->sock));
  716.     free(fi);
  717.     return INST_ERROR;
  718.     }
  719.  
  720.     return ftpinstGetFile(fi, buf, *realName);
  721. }
  722.  
  723. int tapeOp(int fd, int cmd, int count, int reportErr) {
  724.     struct mtop mtcmd;
  725.  
  726.     mtcmd.mt_op = cmd;
  727.     mtcmd.mt_count = count;
  728.  
  729.     if (ioctl(fd, MTIOCTOP, &mtcmd)) {
  730.     if (reportErr)
  731.         messageWindow("Tape Error", "tape ioctl %d failed: %s",
  732.               cmd, strerror(errno));
  733.     return 1;
  734.     }
  735.  
  736.     return 0;
  737. }
  738.  
  739. static int tapeSetup(struct installMethod * method, struct partitionTable table,
  740.                  struct netConfig * netc, struct netInterface * intf,
  741.                  struct driversLoaded ** dl) {
  742.     int rc;
  743.     int fd;
  744.     int catalogAlloced;
  745.     struct tapeinfo * info;
  746.     char magic[5];
  747.     int foundit = 0;
  748.     char catalogBuf[16384];
  749.     char * chptr, * start, * next;
  750.     int offset = 0;
  751.  
  752.     /* eventually we should support devices other then /dev/nst0 */
  753.     if ((rc = setupSCSIInterfaces(1, dl))) return rc;
  754.  
  755.     if ((rc = devMakeInode("nst0", "/tmp/nst0"))) return rc;
  756.  
  757.     if ((fd = open("/tmp/nst0", O_RDONLY)) < 0) {
  758.     devRemoveInode("/tmp/nst0");
  759.  
  760.     if (errno == ENODEV) {
  761.         messageWindow("Error", "I couldn't find any SCSI tape drives.");
  762.     } else {
  763.         errorWindow("Error opening device nst0: %s");
  764.     }
  765.  
  766.     return INST_ERROR;
  767.     }
  768.  
  769.     winStatus(45, 3, "Tape", "Looking for Red Hat tape image...");
  770.  
  771.     /* now, let's see if we can find the file on the tape */
  772.     if ((rc = read(fd, magic, sizeof(magic))) == sizeof(magic)) {
  773.     if (!strcmp(magic, "1234\n")) {
  774.         logMessage("found magic on first try");
  775.         foundit = 1;
  776.     }
  777.     } else if (rc < 0) {
  778.     messageWindow("Error", "Error reading from tape: %s", strerror(errno));
  779.     }
  780.  
  781.     if (!foundit) {
  782.     logMessage("seeking to next file");
  783.     if (tapeOp(fd, MTFSF, 1, 0)) {
  784.         logMessage("failed to find beginning of next file: %s",
  785.             strerror(errno));
  786.     } else {
  787.         if ((rc = read(fd, magic, sizeof(magic))) == sizeof(magic)) {
  788.         if (!strcmp(magic, "1234\n")) {
  789.             logMessage("found magic on second try");
  790.             foundit = 1;
  791.             offset = 1;
  792.         }
  793.         }
  794.     }
  795.     }
  796.  
  797.     if (!foundit) {
  798.     errorWindow("I can't find the Red Hat tape installation image"
  799.             "on that tape.");
  800.     close(fd);
  801.     newtPopWindow();
  802.  
  803.     return INST_ERROR;
  804.     } 
  805.  
  806.     if ((rc = read(fd, catalogBuf, sizeof(catalogBuf) - 1)) < 0) {
  807.     errorWindow("Error reading file catalog from tape: %s");
  808.     newtPopWindow();
  809.     close(fd);
  810.     return INST_ERROR;
  811.     }
  812.  
  813.     newtPopWindow();
  814.  
  815.     info = malloc(sizeof(*info));
  816.     info->fd = fd;
  817.     info->offset = offset;
  818.     info->curr = -1;
  819.     method->data = info;
  820.         
  821.     /* read in the catalog */
  822.     catalogAlloced = 20;
  823.     info->catalog = malloc(sizeof(*info->catalog) * catalogAlloced);
  824.     info->catalogEntries = 0;
  825.  
  826.     start = catalogBuf;
  827.     while (strncmp(start, "--done--", 8)) {
  828.     chptr = strchr(start, '\n');
  829.     next = chptr + 1;
  830.     *chptr = '\0';
  831.     while (*chptr != ' ') chptr--;
  832.     *chptr = '\0';
  833.     chptr++;
  834.  
  835.     if (info->catalogEntries == catalogAlloced) {
  836.         catalogAlloced += 20;
  837.             info->catalog = realloc(info->catalog, 
  838.                     sizeof(*info->catalog) * catalogAlloced);
  839.     }
  840.     
  841.     info->catalog[info->catalogEntries].filename = strdup(start);
  842.     info->catalog[info->catalogEntries].size = strtoul(chptr, NULL, 10);
  843.     info->catalogEntries++;
  844.     
  845.     start = next;
  846.     }
  847.     
  848.     return 0;
  849. }
  850.  
  851. static int tapeGetPackageSet(struct installMethod * method,
  852.                  struct pkgSet * ps) {
  853.     struct tapeinfo * info = method->data;
  854.  
  855.     if (tapeOp(info->fd, MTFSF, 1, 1)) return INST_ERROR;
  856.     info->curr++;
  857.     return psFromHeaderListDesc(info->fd, ps, 1);
  858. }
  859.  
  860. static int tapeCopyFile(struct tapeinfo * info, char * tapename, char * out) {
  861.     int outfd;
  862.     char buf[4096];
  863.     int i;
  864.     int total, amount;
  865.     int done = 0;
  866.  
  867.     /* let's figure out where we need to go */
  868.     for (i = 0; i < info->catalogEntries; i++) {
  869.     if (!strcmp(tapename, info->catalog[i].filename)) break;
  870.     }
  871.  
  872.     if (i < 0) {
  873.     messageWindow("Error", "I can't find file %s on the tape", tapename);
  874.     return INST_ERROR;    
  875.     }
  876.  
  877.     if (i < info->curr) {
  878.     messageWindow("Error", "The tape is not positioned properly");
  879.     return INST_ERROR;    
  880.     } else {
  881.     logMessage("skipping %d files on the tape to get to %s", 
  882.             i - info->curr, tapename);
  883.     while (i > info->curr) {
  884.         if (tapeOp(info->fd, MTFSF, 1, 1)) return INST_ERROR;
  885.         logMessage("skipped file");
  886.         info->curr++;
  887.     }
  888.     }
  889.  
  890.     if ((outfd = open(out, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) {
  891.     messageWindow("Error", "failed to create %s: %s", out, 
  892.             strerror(errno));
  893.     return INST_ERROR;
  894.     }
  895.  
  896.     total = 0;
  897.     while (!done) {
  898.     amount = read(info->fd, buf, sizeof(buf));
  899.  
  900.     if (amount < 0)
  901.         break;
  902.     
  903.     if (((total + amount) > info->catalog[i].size)) {
  904.         done = 1;
  905.         amount = info->catalog[i].size - total;
  906.     }
  907.     if (write(outfd, buf, amount) != amount) {
  908.         messageWindow("Error", "failed to write to %s: %s", out, 
  909.                 strerror(errno));
  910.         close(outfd);
  911.         return INST_ERROR;
  912.     }
  913.  
  914.     total += amount;
  915.     }
  916.  
  917.     if (i < 0) {
  918.     messageWindow("Error", "failed to read from tape: %s", out, 
  919.             strerror(errno));
  920.     close(outfd);
  921.     return INST_ERROR;
  922.     }
  923.  
  924.     close(outfd);
  925.  
  926.     return 0;
  927. }
  928.  
  929. static int tapeGetComponentSet(struct installMethod * method,
  930.                  struct pkgSet * ps,
  931.                  struct componentSet * cs) {
  932.     struct tapeinfo * info = method->data;
  933.     int rc;
  934.     
  935.     if ((rc = tapeCopyFile(info, "comps", "/tmp/comps"))) return rc;
  936.  
  937.     return psReadComponentsFile("/tmp/comps", ps, cs);
  938. }
  939.  
  940. static int tapeGetMappedFile(struct installMethod * method, char * name, 
  941.                         char ** realName, int isPreskel) {
  942.     static char sbuf[300];
  943.     int rc;
  944.     struct tapeinfo * info = method->data;
  945.  
  946.     if (isPreskel)
  947.     strcpy(sbuf, "/mnt/");
  948.     else
  949.     strcpy(sbuf, "/mnt/var/tmp/");
  950.  
  951.     strcat(sbuf, name);
  952.     *realName = sbuf;
  953.  
  954.     return (rc = tapeCopyFile(info, name, sbuf));
  955. }
  956.  
  957. #ifdef __i386__
  958. static int smbSetup(struct installMethod * method, struct partitionTable table,
  959.                struct netConfig * netc, struct netInterface * intf,
  960.                struct driversLoaded ** dl) {
  961.     char * host = NULL, * dir = NULL, * acct = NULL, * pass = NULL;
  962.     char * buf;
  963.     static int moduleLoaded = 0;
  964.     enum { SMB_STEP_NET, SMB_STEP_INFO, SMB_STEP_MOUNT, SMB_STEP_DONE }
  965.         step = SMB_STEP_NET;
  966.     int rc;
  967.  
  968.     while (step != SMB_STEP_DONE) {
  969.     switch (step) {
  970.       case SMB_STEP_NET:
  971.         rc = bringUpNetworking(intf, netc, dl);
  972.         if (rc) return rc;
  973.         step = SMB_STEP_INFO;
  974.         break;
  975.  
  976.       case SMB_STEP_INFO:
  977.         rc = smbGetSetup(&host, &dir, &acct, &pass);
  978.         if (rc == INST_CANCEL)
  979.         step = SMB_STEP_NET;
  980.         else if (rc == INST_ERROR)
  981.         return INST_ERROR;
  982.         else
  983.         step = SMB_STEP_MOUNT;
  984.         break;
  985.  
  986.       case SMB_STEP_MOUNT:
  987.         if (!strlen(host) || !strlen(dir))
  988.         rc = INST_ERROR;
  989.         else {
  990.         buf = malloc(strlen(host) + strlen(dir) + 10);
  991.         strcpy(buf, host);
  992.         strcat(buf, ":");
  993.         strcat(buf, dir);
  994.  
  995.         if (!moduleLoaded) {
  996.             rc = loadModule("smbfs", DRIVER_FS, DRIVER_MINOR_NONE, dl);
  997.             if (rc) return rc;
  998.             moduleLoaded = 1;
  999.         }
  1000.  
  1001.         rc = doPwMount(buf, "/tmp/rhimage", "smb", 1, 0, acct, pass);
  1002.         if (rc) removeModule("smbfs");
  1003.  
  1004.         free(buf);
  1005.         }
  1006.  
  1007.         if (rc) {
  1008.         step = SMB_STEP_INFO;
  1009.         messageWindow("Error", 
  1010.             "I could not mount that directory from the server");
  1011.         } else {
  1012.             if (access("/tmp/rhimage/RedHat", R_OK)) {
  1013.             step = SMB_STEP_INFO;
  1014.             messageWindow("Error", "That directory does not seem "
  1015.                   "to contain a Red Hat installation tree.");
  1016.             umount("/tmp/rhimage");
  1017.         } else
  1018.             step = SMB_STEP_DONE;
  1019.         }
  1020.  
  1021.         break;
  1022.  
  1023.       case SMB_STEP_DONE:
  1024.         break;
  1025.     }
  1026.     }
  1027.  
  1028.     free(host);
  1029.     free(dir);
  1030.  
  1031.     return 0;
  1032. }
  1033.  
  1034. static int smbGetSetup(char ** hostptr, char ** dirptr, char ** acctptr,
  1035.             char ** pwptr) {
  1036.     newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text;
  1037.     newtComponent acctEntry, passEntry;
  1038.     char * site, * dir, * acct, * pass;
  1039.  
  1040.     if (*hostptr) {
  1041.     site = *hostptr;
  1042.     dir = *dirptr;
  1043.     acct = *acctptr;
  1044.     pass = *pwptr;
  1045.     } else {
  1046.     site = "";
  1047.     dir = "";
  1048.     acct = "";
  1049.     pass = "";
  1050.     }
  1051.  
  1052.     newtOpenWindow(15, 4, 50, 16, "SMB Setup");
  1053.  
  1054.     form = newtForm(NULL, NULL, 0);
  1055.     okay = newtButton(10, 12, "Ok");
  1056.     cancel = newtButton(30, 12, "Cancel");
  1057.  
  1058.     text = newtTextbox(1, 1, 47, 5, NEWT_TEXTBOX_WRAP);
  1059.     newtTextboxSetText(text,
  1060.     "Please enter the following information:\n"
  1061.     "\n"
  1062.     "    o the name or IP number of your SMB server\n"
  1063.     "    o the volume to share which contains\n"
  1064.     "      Red Hat Linux for your architecture");
  1065.  
  1066.     newtFormAddComponent(form, newtLabel(3, 7,  "SMB server name  :"));
  1067.     newtFormAddComponent(form, newtLabel(3, 8,  "Share volume     :"));
  1068.     newtFormAddComponent(form, newtLabel(3, 9,  "Account name     :"));
  1069.     newtFormAddComponent(form, newtLabel(3, 10, "Password         :"));
  1070.  
  1071.     siteEntry = newtEntry(22, 7, site, 24, &site, NEWT_ENTRY_SCROLL);
  1072.     dirEntry = newtEntry(22, 8, dir, 24, &dir, NEWT_ENTRY_SCROLL);
  1073.     acctEntry = newtEntry(22, 9, "guest", 24, &acct, NEWT_ENTRY_SCROLL);
  1074.     passEntry = newtEntry(22, 10, pass, 24, &pass, 
  1075.               NEWT_ENTRY_SCROLL | NEWT_ENTRY_HIDDEN);
  1076.  
  1077.     newtFormAddComponents(form, text, siteEntry, dirEntry, acctEntry,
  1078.               passEntry, okay, cancel, NULL);
  1079.  
  1080.     answer = newtRunForm(form);
  1081.     if (answer == cancel) {
  1082.     newtFormDestroy(form);
  1083.     newtPopWindow();
  1084.     
  1085.     return INST_CANCEL;
  1086.     }
  1087.  
  1088.     *hostptr = strdup(site);
  1089.     *dirptr = strdup(dir);
  1090.     *acctptr = strdup(acct);
  1091.     *pwptr = strdup(pass);
  1092.  
  1093.     newtFormDestroy(form);
  1094.     newtPopWindow();
  1095.  
  1096.     return 0;
  1097. }
  1098.  
  1099. static int smbGetPackageSet(struct installMethod * method,
  1100.                  struct pkgSet * ps) {
  1101.     return psUsingDirectory("/tmp/rhimage/RedHat/RPMS", ps);
  1102. }
  1103.  
  1104. static int smbGetComponentSet(struct installMethod * method,
  1105.                    struct pkgSet * ps,
  1106.                    struct componentSet * cs) {
  1107.     return psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs);
  1108. }
  1109.  
  1110.  
  1111. #endif
  1112.